﻿using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web.Mvc;
using Viettel.VOFFICE.DAO.DAL;
using Viettel.VOFFICE.DAO.Models;
using Viettel.VOFFICE.Web.Helpers;
using Viettel.VOFFICE.Web.Models;
using Viettel.VOFFICE.util;

namespace Viettel.VOFFICE.Web.Controllers
{
    /// <summary>
    /// Xử lý các node trong luồng
    /// </summary>
    public class NodeController : BaseController
    {
        /// <summary>
        /// Lấy toàn bộ nút bởi id luồng
        /// </summary>
        /// <param name="flowId"></param>
        /// <returns></returns>
        [HttpGet]
        [ActionName("get_by_flow_id")]
        public JsonResult GetByFlow(int flowId)
        {
            try
            {
                var items = unitOfWork.NodeRepository.GetByFlow(flowId).Select(o => new NodeModel(o));
                return Json(new JsonResponse()
                                {
                                    Status = true,
                                    Result = items
                                }, JsonRequestBehavior.AllowGet);
            }
            catch (Exception)
            {
                return Json(SimplyResponse.Response500(), JsonRequestBehavior.AllowGet);
                //throw;
            }
        }

        /// <summary>
        /// Thêm mới một node
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        [HttpPost]
        [ActionName("add_node")]
        [ValidateJsonAntiForgeryToken(Salt = AppConstants.TokenSalt)]
        public JsonResult AddNode(NodeModel node)
        {
            try
            {
                List<ValidationResult> outError;
                if (node.IsValid(out outError))
                {
                    var dbNode = new Node()
                                     {
                                         Name = node.Name,
                                         Description = node.Description,
                                         FlowId = node.FlowId,
                                         RoleId = node.RoleId,
                                         IsDocNode = node.IsDocNode,
                                         IsStart = node.IsStart,
                                         CreatedAt = DateTime.Now,
                                         UpdatedAt = DateTime.Now
                                     };
                    unitOfWork.NodeRepository.Insert(dbNode);
                    return Json(SimplyResponse.ResposeWithId(dbNode.Id));
                }
                else
                {
                    return Json(new JsonResponse()
                                    {
                                        Status = false,
                                        Result = string.Join(", ", outError.Select(o => o.ErrorMessage))
                                    });
                }
            }
            catch (Exception)
            {
                return Json(SimplyResponse.Response500());
                //throw;
            }
        }

        /// <summary>
        /// Cập nhập node
        /// </summary>
        /// <param name="node"></param>
        /// <param name="modified"></param>
        /// <returns></returns>
        [HttpPut]
        [ActionName("update_node")]
        [ValidateJsonAntiForgeryToken(Salt = AppConstants.TokenSalt)]
        public JsonResult UpdateNode(NodeModel node, string modified = "all")
        {
            ITransaction transaction = null;
            try
            {
                List<ValidationResult> outError;
                if (node.IsValid(out outError))
                {

                    var uow = new UnitOfWork();
                    transaction = uow.BeginTransaction();
                    var dbNode = uow.NodeRepository.GetById(node.Id);
                    if (dbNode == null)
                    {
                        return Json(new JsonResponse()
                            {
                                Status = false,
                                Result = Resources.Resources.ManageNodeNotFound
                            });
                    }
                    if (modified == "all")
                    {
                        dbNode.Name = node.Name;
                        dbNode.Description = node.Description;
                        dbNode.FlowId = node.FlowId;
                        dbNode.RoleId = node.RoleId;
                        dbNode.IsDocNode = node.IsDocNode;
                        dbNode.IsStart = node.IsStart;
                        dbNode.UpdatedAt = DateTime.Now;
                        if (dbNode.IsStart == true)
                        {
                            //loại bỏ hết các nút đã được đánh dấu start trước đó
                            uow.NodeRepository.UpdateStarting(node.FlowId, node.Id);
                        }
                    }
                    else if (modified == "IsStart")
                    {
                        dbNode.IsStart = node.IsStart;
                        if (dbNode.IsStart == true)
                        {
                            uow.NodeRepository.UpdateStarting(node.FlowId, node.Id);
                        }
                    }
                    else if (modified == "IsDocNode")
                    {
                        dbNode.IsDocNode = node.IsDocNode;
                    }
                    uow.NodeRepository.Update(dbNode);

                    transaction.Commit();
                    return Json(SimplyResponse.ResposeWithId(dbNode.Id));

                }
                else
                {
                    return Json(new JsonResponse()
                        {
                            Status = false,
                            Result = string.Join(", ", outError.Select(o => o.ErrorMessage))
                        });

                }
            }
            catch (Exception)
            {
                if (transaction != null) transaction.Rollback();
                return Json(SimplyResponse.Response500());
                //throw;
            }
            finally
            {
                if (transaction != null) transaction.Dispose();
            }
        }

        /// <summary>
        /// Xóa một node trong luồng (xóa đồng thời hết các thông tin như: node-relation, node-user, _todo của node)
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpPost]
        [ActionName("delete_node")]
        [ValidateJsonAntiForgeryToken(Salt = AppConstants.TokenSalt)]
        public JsonResult DeleleNode(int id)
        {
            try
            {
                ITransaction transaction = null;
                try
                {
                    var unitofwork = new UnitOfWork();
                    transaction = unitofwork.BeginTransaction();
                    unitofwork.TodoRepository.DeleteByNode(id);
                    unitofwork.NodeUserRepository.DeleteByNodeId(id);
                    unitofwork.NodeRelationRepository.DeleteByAnyId(id);
                    unitofwork.NodeRepository.Delete(id);
                    transaction.Commit();
                    return Json(SimplyResponse.Response200());
                }
                catch (Exception)
                {
                    if (transaction != null) transaction.Rollback();
                    return Json(SimplyResponse.Response500());
                    throw;
                }
                finally
                {
                    if (transaction != null) transaction.Dispose();
                }
            }
            catch (Exception)
            {
                return Json(SimplyResponse.Response500());
                //throw;
            }
        }
    }
}
